﻿#include "udp_session.h"
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <errno.h>
#include <stdbool.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#include <inttypes.h>
#include <pthread.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/time.h>
//#include <json-c/json.h>
#include <list>

#include <json/json.h>

#include <unordered_map>
#include <functional>
#include "common/global_include.h"

static bool m_bPushConn = false; //push连接状态
udp_push_client__t  client;

bool is_command_success(const char* cmd)
{
	char buffer[128];
	FILE* fp;
	int num;
	bool result = false;

	fp = popen(cmd, "r");
	if (fp != NULL) {
		num = fread(buffer, 1, sizeof(buffer), fp);
		if (num > 0)
			result = true;
		pclose(fp);
	}

	return result;
}

struct json_data {
	int id;
	char* path;
	bool add;
};

static std::list<int> g_fail_id;
static std::list<struct json_data*> g_json;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_t g_th;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
static bool g_flag;

extern int g_face_width;
extern int g_face_height;

void MV_STDCALL on_status(const char* id, const uint8_t priority, const mv::connect_status old_status, const mv::connect_status new_status)
{
    // DebugL() <<(uint32_t)priority;
    // DebugL() <<static_cast<int32_t>(old_status);
    // DebugL() <<static_cast<int32_t>(new_status);
    Push_ConnectState(static_cast<int32_t>(new_status));
}

void MV_STDCALL on_message_received(const char* id, const uint8_t* message, const int32_t length)
{
    std::string value = std::string((const char*)message, length);
    analysisReplydata(value.c_str());
}


void Push_ConnectState(int i) {
		if(i == 1) {
			if(m_bPushConn == false){
				printf("mvpush connected!\n");
				toolkit::NoticeCenter::Instance().emitEvent("udp_push_status", 1);		//连接成功
				
			}
			m_bPushConn = true;
		}
		else{
			if(m_bPushConn == true){
				printf("mvpush connect failed!\n");
				toolkit::NoticeCenter::Instance().emitEvent("udp_push_status", 0);		//连接失败
			}
			m_bPushConn = false;
		}
}

void Push_Connect(char* sgateno, char* iphost, int32_t iport) {
	//printf("mvpush  create!\n");
	InfoL << "mvpush create";

	//m_pLocalIp = sgateno;

	client = udp_create(sgateno,iphost,iport,(uint8_t)0);
    //udp_bind_local_ip(client,sgateno);
    udp_start(client, on_status, on_message_received);

    udp_check_connect_status(client, mv::connect_status::connected, 1000);
}

void analysisReplydata(const std::string &replydata) {
//解析接收到的push数据
	// printf("udppush_rev data:%s\n",replydata.c_str()); 
	Json::Value root;
	Json::Reader reader;
	if (!reader.parse(replydata, root))
		return;
	InfoL << "push revdata: " << replydata;
	processReplyData(root);
}

void processReplyData(Json::Value value) {
	if (value.isMember("cmdNo")) {
		int iStatus = -1;
		int iCmdNo = value["cmdNo"].asInt();
		std::string sData = "";
		Json::Value jData = value["data"];
		 if (iCmdNo == 3) {					//车牌识别
			iStatus = jData["status"].asInt();
			sData = jData["plateNo"].asString();
		 } else if (iCmdNo == 8) {	  //放行状态
		 Json::Value jStatus = jData["status"];
			for(int i=0; i<jStatus.size(); i++){
				std::string  unitId = jStatus[i]["unitId"].asString();
				iStatus = jStatus[i]["unitStatus"].asInt();
			}
		 } else if (iCmdNo == 10) {
			 	iStatus = jData["status"].asInt();
				sData = jData["height"].asString();
		 } else if (iCmdNo == 12) {
			 	iStatus = jData["personNum"].asInt();
				sData = jData["height"].asString();
		 }
		 else {
			 	iStatus = jData["status"].asInt();
		 }
		 toolkit::NoticeCenter::Instance().emitEvent("udp_push_process", iCmdNo,iStatus,sData);
	}	
}

bool sendPushData(std::string sData) {
	if (!m_bPushConn) {
		InfoL << "push disconnected!";
		return false;
	}
	// size_t length = sData.length();
	// std::vector<unsigned char> data(length + 1);
	//     // 将std::string转换为UTF-8编码的unsigned char*
    // std::memcpy(&data[0], sData.c_str(), length);
	// unsigned char* pData = &data[0];
	//if(udp_send_msg(m_pLocalIp, (uint8_t *)pData, length)){

	if(udp_send_msg(getLocalClientID(), (uint8_t *)sData.c_str(), sData.length())) {
		InfoL << "push data success <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
		return true;
	} else {
		InfoL << "push data failed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" ;
		return false;
	}
}

//推送OCR信息
void pushOCRData(const int iStatus, const std::string &sOcrData) {
	std::vector<std::string> sCmdLst = SplitString(sOcrData,",");
//上传OCR数据以及图片数据,按照V2版本
	Json::Value ocrValue;
	Json::FastWriter writer;
	std::string json_file;

	ocrValue["cmdNo"] = 5;
	ocrValue["channelNo"] = getChannelID();
	ocrValue["sid"] = getSessionID();
	ocrValue["time"] = std::stoi(getCurrentTimestamp());
	ocrValue["data"]["status"] = iStatus;

	if (iStatus == 0) {
		json_file = writer.write(ocrValue);
		InfoL << "push ocr data" <<  json_file;
		sendPushData(json_file);
		return;
	}

	Json::Value jsonReader(Json::arrayValue);

	Json::Value data1;
    data1["dataType"] = "OCR_DOC_TYPE";
    data1["dataValue"] = sCmdLst[0];
    data1["desc"] = "证件类型";

    Json::Value data2;
    data2["dataType"] = "OCR_SURNAME";
    data2["dataValue"] = sCmdLst[1];
    data2["desc"] = "姓";

    Json::Value data3;
    data3["dataType"] = "OCR_FORENAME";
    data3["dataValue"] = sCmdLst[2];
    data3["desc"] = "名";

    Json::Value data4;
    data4["dataType"] = "OCR_DATE_OF_BIRTH";
    data4["dataValue"] = sCmdLst[3];
    data4["desc"] = "出生日期";

    Json::Value data5;
    data5["dataType"] = "OCR_EXPIRY_DATE";
    data5["dataValue"] = sCmdLst[4];
    data5["desc"] = "有效期";

    Json::Value data6;
    data6["dataType"] = "OCR_NATIONALITY";
    data6["dataValue"] = sCmdLst[5];
    data6["desc"] = "国籍";

    Json::Value data7;
    data7["dataType"] = "OCR_DOC_NUMBER";
    data7["dataValue"] = sCmdLst[6];
    data7["desc"] = "证件号码";

    Json::Value data8;
    data8["dataType"] = "OCR_SEX";
    data8["dataValue"] = sCmdLst[7];
    data8["desc"] = "性别";

    Json::Value data9;
    data9["dataType"] = "OCR_ID_PHOTO";
    data9["dataValue"] = sCmdLst[8];
    data9["desc"] = "证件照片";

    Json::Value data10;
    data10["dataType"] = "OCR_FACE_SCREENSHOT";
    data10["dataValue"] = sCmdLst[9];
    data10["desc"] = "人脸截图";

    Json::Value data11;
    data11["dataType"] = "OCR_ELECTRONIC_PHOTO";
    data11["dataValue"] = sCmdLst[10];
    data11["desc"] = "电子照片";

    Json::Value data12;
    data12["dataType"] = "TERMINAL_IP_ADDRESS";
    data12["dataValue"] = sCmdLst[11];
    data12["desc"] = "终端IP地址";

    Json::Value data13;
    data13["dataType"] = "TERMINAL_MAC_ADDRESS";
    data13["dataValue"] = sCmdLst[12];
    data13["desc"] = "终端MAC地址";

    jsonReader.append(data1);
    jsonReader.append(data2);
    jsonReader.append(data3);
    jsonReader.append(data4);
    jsonReader.append(data5);
    jsonReader.append(data6);
    jsonReader.append(data7);
    jsonReader.append(data8);
    jsonReader.append(data9);
    jsonReader.append(data10);
    jsonReader.append(data11);
    jsonReader.append(data12);
    jsonReader.append(data13);

	ocrValue["data"]["reader"] = jsonReader;
	json_file = writer.write(ocrValue);
	InfoL << "push ocr data" <<  json_file;
	sendPushData(json_file);
}

//推送人脸信息
void pushFaceData(const std::string &sFaceData) {
	std::vector<std::string> sCmdLst = SplitString(sFaceData,",");
	//上传人脸照片以及人脸热证参数
	Json::Value faceValue;
	Json::FastWriter writer;
	std::string json_file;
	
	faceValue["cmdNo"] = 6;
	faceValue["channelNo"] = getChannelID();
	faceValue["sid"] = getSessionID();
	faceValue["time"] = std::stoi(getCurrentTimestamp());
	faceValue["data"]["eyesOpen"] = std::stoi(sCmdLst[0]);
	faceValue["data"]["eyesScore"] = std::stoi(sCmdLst[1]);
	faceValue["data"]["faceBrightness"] = std::stoi(sCmdLst[2]);
	faceValue["data"]["faceClarity"] = std::stoi(sCmdLst[3]);
	faceValue["data"]["facePicture"] = sCmdLst[4];
	faceValue["data"]["faceResult"] = sCmdLst[5];
	faceValue["data"]["faceScore"] = std::stoi(sCmdLst[6]);
	json_file = writer.write(faceValue);
	InfoL << "push face data" <<  json_file;
	sendPushData(json_file);
 }

//推送虹膜信息
void pushIrisData(const std::string &sIrisData) {
	std::vector<std::string> sCmdLst = SplitString(sIrisData,",");

	//上传人脸照片以及人脸热证参数
	Json::Value irisValue;
	Json::FastWriter writer;
	std::string json_file;
	
	irisValue["cmdNo"] = 9;
	irisValue["channelNo"] = getChannelID();
	irisValue["sid"] = getSessionID();
	irisValue["time"] = std::stoi(getCurrentTimestamp());
	irisValue["data"]["irisBrightness"] = std::stoi(sCmdLst[0]);
	irisValue["data"]["irisClarity"] = std::stoi(sCmdLst[1]);
	irisValue["data"]["irisQuality"] = std::stoi(sCmdLst[2]);
	irisValue["data"]["irisScore"] = std::stoi(sCmdLst[3]);
	irisValue["data"]["irisResult"] = sCmdLst[4];
	irisValue["data"]["irisPicture"] = sCmdLst[5];
	irisValue["data"]["irisLeftEyePicture"] = sCmdLst[6];
	irisValue["data"]["irisRightEyePicture"] = sCmdLst[7];
	json_file = writer.write(irisValue);
	InfoL << "push iris data" <<  json_file;
	sendPushData(json_file);
}

//推送通关人数
void pushPersonNumberData(const std::string &sNumberData, const std::string &sHeightData) {
	Json::Value dataValue;
	Json::FastWriter writer;
	std::string json_file;
	dataValue["cmdNo"] = 12;
	dataValue["channelNo"] = getChannelID();
	dataValue["sid"] = getSessionID();
	dataValue["time"] = std::stoi(getCurrentTimestamp());
	dataValue["data"]["personNum"] = std::stoi(sNumberData);
	dataValue["data"]["height"] = std::stoi(sHeightData);
	json_file = writer.write(dataValue);
	InfoL << "push person number data" <<  json_file;
	sendPushData(json_file);
}

void pushTerminalStatus(const std::string &sData) {
	//扫描枪、阅读器、人脸设备、打印机、下位机、终端系统
		std::vector<std::string> sCmdLst = SplitString(sData,",");
		Json::Value dataValue;
		Json::FastWriter writer;
		std::string json_file;
		dataValue["cmdNo"] = 1;
		dataValue["channelNo"] = getChannelID();
		dataValue["sid"] = getSessionID();
		dataValue["time"] = std::stoi(getCurrentTimestamp());

		Json::Value jsonReader(Json::arrayValue);
		Json::Value data1;
		data1["deviceId"] = 0;
		data1["deviceStatus"] = std::stoi(sCmdLst[0]);

		Json::Value data2;
		data2["deviceId"] = 1;
		data2["deviceStatus"] = std::stoi(sCmdLst[1]);

		Json::Value data3;
		data3["deviceId"] = 2;
		data3["deviceStatus"] = std::stoi(sCmdLst[2]);

		Json::Value data4;
		data4["deviceId"] = 3;
		data4["deviceStatus"] = std::stoi(sCmdLst[3]);

		Json::Value data5;
		data5["deviceId"] = 4;
		data5["deviceStatus"] = std::stoi(sCmdLst[4]);

		Json::Value data6;
		data6["deviceId"] = 5;
		data6["deviceStatus"] = std::stoi(sCmdLst[5]);

		jsonReader.append(data1);
		jsonReader.append(data2);
		jsonReader.append(data3);
		jsonReader.append(data4);
		jsonReader.append(data5);
		jsonReader.append(data6);
		dataValue["data"] = jsonReader;
		json_file = writer.write(dataValue);
		InfoL << "push terminal status" <<  json_file;
		sendPushData(json_file);
}


void pushVehicleDistance(const int heught,const int width){
	Json::Value dataValue;
	Json::FastWriter writer;
	std::string json_file;
	dataValue["cmdNo"] = 13;
	dataValue["channelNo"] = getChannelID();
	dataValue["sid"] = getSessionID();
	dataValue["time"] = std::stoi(getCurrentTimestamp());
	dataValue["data"]["height"] = heught;
	dataValue["data"]["width"] = width;
	json_file = writer.write(dataValue);
	InfoL << "push vehicle diatance :" <<  json_file;
	sendPushData(json_file);
}

//推送设备到位信号
void pushDeviceSignal(const int iDeviceSignal) {
	//升降到位、伸缩到位
}

//流程切换
void pushProcessSwitch(const int iProcess) {

}